﻿Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.IO
'保存断面的观测点信息

<Serializable()> Public Class TunnelSectionPoints

    Public Points As List(Of SectionPoint) '所有观测点
    Public InstrHeight As Double = 0 '仪器高
    Public SectionNo As String = "" '断面号
    Public SectionLen As String = "" '断面里程
    Public StdErr As Double         '该组点拟合出来圆的中误差

    Public Sub New()
        Points = New List(Of SectionPoint)
    End Sub

    Public center As TSPCoor
    Public start_hv As Double
    Public end_hv As Double
    Public Radius As Double
    Public F_Note As Boolean = False
    Public Function Get_Clone() As Object
        Dim mo As New System.IO.MemoryStream()
        Dim bf As BinaryFormatter = New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))
        bf.Serialize(mo, Me)
        mo.Seek(0, SeekOrigin.Begin)
        Dim CloneObject As Object = bf.Deserialize(mo)
        mo.Close()
        Return CloneObject
    End Function
    Function Read(ByVal FileName As String) As Boolean
        Dim sData As String = ""
        Try
            If ReadFile(FileName, sData) Then
                Dim Lines() As String = sData.Split(vbCrLf)
                Dim StationSetPassed As Boolean = False
                Dim dre As FileInfo = New FileInfo(FileName)
                Me.SectionNo = Expand_Name(dre.Name)
                For Each Line As String In Lines
                    Line = Line.Trim
                    If Line.Length > 0 Then
                        Dim v() As String = Line.Split(",")
                        If v.Length = 8 Then

                            If Not StationSetPassed Then
                                Me.InstrHeight = CDbl(v(7))

                                Me.SectionLen = v(4)
                                If v(0).Contains("F") = True Or v(0).Contains("f") = True Then
                                    F_Note = True
                                    StationSetPassed = True
                                End If
                            End If
                            Dim vP As New SectionPoint(v(0), v(1), v(2))
                            Points.Add(vP)

                        End If
                    End If
                Next
                CalculateCoor(New TSPCoor(0, 0))
            Else

                Return False
            End If

        Catch ex As Exception
            Return False
        End Try

        Return True
    End Function
    Function Expand_Name(ByVal name As String) As String
        name = name.Split(".")(0)
        name = name.Replace("L", "")
        name = name.Replace("l", "")
        name = name.Replace("R", "")
        name = name.Replace("r", "")
        If name.Length = 3 Then
            Return name
        ElseIf name.Length = 2 Then
            Return "0" + name
        ElseIf name.Length = 1 Then
            Return "00" + name
        Else
            Return name.Substring(name.Length - 3, 3)
        End If
    End Function
    Private Function ReadFile(ByVal FullFileName As String, ByRef sData As String) As Boolean
        Try
            Dim FN As System.IO.TextReader = New IO.StreamReader(FullFileName)
            sData = FN.ReadToEnd
            FN.Close()
        Catch ex As Exception
            MsgBox(ex.Message)
            Return False
        End Try
        Return True
    End Function

    Sub CalculateCoor(ByVal BaseAtPoint As TSPCoor)
        For Each vP As SectionPoint In Points
            vP.CalculateCoor(BaseAtPoint)
        Next
    End Sub

    Overrides Function ToString() As String
        Dim sTmp As String = String.Empty
        For Each vp As SectionPoint In Points
            sTmp &= vp.ToString() & ","
            sTmp &= String.Format("{0,5}", SectionNo) & ","
            sTmp &= String.Format("{0,8}", SectionLen) & ","
            sTmp &= vp.Coor.ToString & ","
            sTmp &= String.Format("{0,6}", String.Format("{0:0.000}", InstrHeight)) & ","
            Dim az As Double = SvAngle.RadToDms(vp.AzimFromCenter)
            sTmp &= String.Format("{0,9}", String.Format("{0:0.0000}", az)) & vbCrLf
        Next
        Return sTmp
    End Function


    Function FindNear180(ByRef vP_Near180U As TSPCoor, ByRef vP_Near180L As TSPCoor) As Boolean
        Try
            Dim Hv180U As Double = 360
            Dim NoU As Integer = -1
            Dim Hv180L As Double = 0
            Dim NoL As Integer = -1

            For i As Integer = 0 To Points.Count - 1
                Dim vp As SectionPoint = Points.Item(i)
                If vp.Hv > 180 Then
                    If vp.Hv < Hv180U Then
                        Hv180U = vp.Hv
                        NoU = i
                    End If

                Else
                    If vp.Hv > Hv180L Then
                        Hv180L = vp.Hv
                        NoL = i
                    End If

                End If
            Next

            vP_Near180U = Points(NoU).Coor
            vP_Near180L = Points(NoL).Coor

        Catch ex As Exception
            Return False
        End Try

        Return True

    End Function

    Sub CAD_Class()
        ' Dim AcadApp As New AutoCAD.AcadApplication
        Dim AcadDoc As New AutoCAD.AcadDocument
        Dim AcadMo As AutoCAD.AcadModelSpace = AcadDoc.ModelSpace

    End Sub


    Function DrawPointToCAD(ByVal Layer As String) As Boolean

        Dim Acad As AutoCAD.AcadApplication
        Dim AcadDoc As AutoCAD.AcadDocument
        Dim AcadMo As AutoCAD.AcadModelSpace
        Try
            Acad = GetObject(, "AutoCAD.Application")
        Catch ex As Exception
            Err.Clear()
            Try
                Acad = CreateObject("AutoCAD.Application")
            Catch ex1 As Exception
                MsgBox(ex1.Message)
                Return False
            End Try
        End Try
        Try
            AcadDoc = Acad.ActiveDocument
            AcadMo = AcadDoc.ModelSpace
        Catch ex As Exception
            Return False
        End Try
        Try
            Acad.Visible = True
            For Each vP As SectionPoint In Points
                Dim vPc(2) As Double
                vPc(0) = vP.Coor.Coor_H
                vPc(1) = vP.Coor.Coor_V
                vPc(2) = 0

                If ExamLayer(AcadDoc, Layer & "Pnt") Then
                    AcadMo.AddPoint(vPc)
                End If
                If ExamLayer(AcadDoc, Layer & "Name") Then

                    AcadMo.AddText(vP.Name, vPc, 0.1)
                End If

            Next
        Catch ex As Exception

        End Try
    End Function
    Private Function ExamLayer(ByRef AcadDoc As AutoCAD.AcadDocument, ByVal Layer As String) As Boolean
        Try
            AcadDoc.Layers.Add(Layer)
        Catch ex As Exception
        End Try
        Try
            For Each tLy As AutoCAD.AcadLayer In AcadDoc.Layers
                If tLy.Name = Layer Then
                    AcadDoc.ActiveLayer = tLy
                    Return True
                End If
            Next
        Catch ex As Exception
            Return False
        End Try
        Return False
    End Function


    Public Sub SortByHv()
        Points.Sort(AddressOf CompareDinosHv)
    End Sub
    '倒序排序
    Private Function CompareDinosHv(ByVal P1 As SectionPoint, ByVal P2 As SectionPoint) As Integer

        Dim p1C As Double = IIf(P1.Hv > 180, P1.Hv, P1.Hv + 360)
        Dim p2C As Double = IIf(P2.Hv > 180, P2.Hv, P2.Hv + 360)
        Return p1C.CompareTo(p2C)
    End Function


    'Sub DrawPoints(ByRef PctBox As PictureBox)
    '    Dim mDraw As SvDrawing = New SvDrawing(PctBox)
    '    mDraw.SetScale(7, 7)

    '    For Each pt As SectionPoint In Points
    '        Dim ptcr As TSPCoor = pt.Coor
    '        If pt.IsValid Then
    '            mDraw.DrawPoint(ptcr, 3, Color.Blue)
    '        Else
    '            mDraw.DrawPoint(ptcr, 3, Color.Red)
    '        End If

    '    Next
    'End Sub

    Sub CalAzimFromCenter(ByVal Center As TSPCoor)
        For Each pt As SectionPoint In Points
            pt.AzimFrom(Center)
        Next
    End Sub

    Sub SetToValid()
        For Each pt As SectionPoint In Points
            pt.IsValid = True
        Next
    End Sub

    ReadOnly Property ValidPointCount() As Integer
        Get
            Dim Cnt As Integer = 0
            For Each p As SectionPoint In Points
                If p.IsValid Then
                    Cnt += 1
                End If
            Next
            Return Cnt
        End Get
    End Property

    '计算较差 ,主要是跟设计圆半径(2.75m)相比的差值
    Public Sub Call_Arc_Err()
        If center Is Nothing Then
            Points.Clear()
            Return
            Throw New ApplicationException("Exception Occured")
        End If
        For i As Integer = 0 To Points.Count - 1
            Dim v As SvVector = New SvVector(Me.center, Points(i).Coor)
            Points(i).Dist_frm_Center = v.Distance
            Points(i).Err_Distance = v.Distance - 2.75
        Next
    End Sub
    Public Function Clone() As Object
        Return Me.MemberwiseClone()
    End Function
    '这个函数主要跟自己拟合出来的圆进行比较
    Public Sub Call_Arc_Err1()
        Dim err As Double = 0
        If center Is Nothing Then
            Points.Clear()
            Return
            Throw New ApplicationException("Exception Occured")
        End If
        If Points.Count = 0 Then
            Return
        End If
        For i As Integer = 0 To Points.Count - 1
            Dim v As SvVector = New SvVector(Me.center, Points(i).Coor)
            err = err + (v.Distance - Me.Radius) * (v.Distance - Me.Radius)
        Next
        err = err / Points.Count
        Me.StdErr = err
        start_hv = Points(0).AzimFrom(center)
        end_hv = Points(Points.Count - 1).AzimFrom(center)
    End Sub

    Public Sub Adjudt_Unified(ByVal Dv As Double)
        For i As Integer = 0 To Points.Count - 1
            Points(i).Coor.Coor_V = Points(i).Coor.Coor_V + Dv

        Next

    End Sub
End Class

